package com.smartfactory.sail.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smartfactory.sail.entity.Logistics;
import com.smartfactory.sail.entity.OrderItem;
import com.smartfactory.sail.entity.OrderLogistics;
import com.smartfactory.sail.entity.StorageCurrentInfo;
import com.smartfactory.sail.entity.enums.LogisticsStatusEnum;
import com.smartfactory.sail.entity.enums.OrderItemStatusEnum;
import com.smartfactory.sail.entity.enums.StorageType;
import com.smartfactory.sail.mapper.LogisticsMapper;
import com.smartfactory.sail.mapper.StorageCurrentInfoMapper;
import com.smartfactory.sail.service.ILogisticsService;
import com.smartfactory.sail.service.IOrderItemService;
import com.smartfactory.sail.service.IOrderLogisticsService;
import com.smartfactory.sail.vo.PageParam;
import com.smartfactory.sail.vo.logistics.ListLogisticsForStorage;
import com.smartfactory.sail.vo.logistics.LogisticsResp;
import com.smartfactory.sail.vo.order.OrderLogisticsReq;
import com.smartfactory.sail.vo.order.OrderLogisticsResp;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;

/**
 * <p>
 * 物流信息表 服务实现类
 * </p>
 *
 * @author 王巨壁
 * @since 2019-07-24
 */
@Service
public class LogisticsServiceImpl extends ServiceImpl<LogisticsMapper, Logistics> implements ILogisticsService {

    private LogisticsMapper logisticsMapper;
    private IOrderLogisticsService iOrderLogisticsService;
    private IOrderItemService iOrderItemService;
    private StorageCurrentInfoMapper storageCurrentInfoMapper;

    public LogisticsServiceImpl(LogisticsMapper logisticsMapper, IOrderLogisticsService iOrderLogisticsService, IOrderItemService iOrderItemService, StorageCurrentInfoMapper storageCurrentInfoMapper) {
        this.logisticsMapper = logisticsMapper;
        this.iOrderLogisticsService = iOrderLogisticsService;
        this.iOrderItemService = iOrderItemService;
        this.storageCurrentInfoMapper = storageCurrentInfoMapper;
    }

    @Override
    public boolean saveLogistics(OrderLogisticsReq orderLogisticsReq) {
        Logistics logistics = new Logistics();
        BeanUtils.copyProperties(orderLogisticsReq, logistics);
        logistics.setLogisticsStatus(LogisticsStatusEnum.YFH);
        save(logistics);
        Long logisticsId = logistics.getId();
        List<OrderLogistics> items = orderLogisticsReq.getItems();
        items.forEach(orderLogistics -> orderLogistics.setLogisticsId(logisticsId));
        boolean saveBatch = iOrderLogisticsService.updateBatchById(items);
        items.forEach(orderLogistics -> {
            OrderItem orderItem = iOrderItemService.findByOrderIdAndItemId(orderLogistics.getItemId(), orderLogistics.getOrderId());
            orderItem.setShippedSize(orderItem.getShippedSize() + orderLogistics.getSize());
            orderItem.setShippedCount(orderItem.getShippedCount() + 1);
            orderItem.setStatus(OrderItemStatusEnum.FHZ);
//            if (orderItem.getSize().equals(orderItem.getShippedSize()))
//                orderItem.setStatus(OrderItemStatusEnum.YWC);

            iOrderItemService.updateById(orderItem);

            StorageCurrentInfo currentInfo = storageCurrentInfoMapper.getByItemId(orderLogistics.getItemId(), StorageType.CPK.getCode());
            currentInfo.setAllocatableSize(currentInfo.getAllocatableSize() - orderLogistics.getSize());
            storageCurrentInfoMapper.updateById(currentInfo);
        });

        return saveBatch;
    }

    @Override
    public List<OrderLogisticsResp> findLogistics(long orderId) {
        List<OrderLogisticsResp> logistics = logisticsMapper.findLogistics(orderId);
        logistics.forEach(orderLogisticsResp -> {
            orderLogisticsResp.setCompanyAndDriverName(orderLogisticsResp.getLogisticsCompanyName() + "/" + orderLogisticsResp.getDriverName());
            orderLogisticsResp.setLogisticsCodeAndPhone(orderLogisticsResp.getLogisticsCode() + "/" + orderLogisticsResp.getPhone());
        });

        return logistics;
    }

    @Override
    public boolean requestLogistics(List<OrderLogistics> logistics) {
        logistics.forEach(orderLogistics -> {
            Long orderId = orderLogistics.getOrderId();
            Long itemId = orderLogistics.getItemId();
            LambdaQueryWrapper<OrderLogistics> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(OrderLogistics::getItemId, itemId);
            queryWrapper.eq(OrderLogistics::getOrderId, orderId);
            queryWrapper.isNull(OrderLogistics::getLogisticsId);
            List<OrderLogistics> logisticsList = iOrderLogisticsService.list(queryWrapper);
            if (CollectionUtils.isEmpty(logisticsList)) {
                orderLogistics.setLogisticsId(null);
                iOrderLogisticsService.save(orderLogistics);
            } else {
                OrderLogistics ol = logisticsList.get(0);
                ol.setSize(ol.getSize() + orderLogistics.getSize());
                iOrderLogisticsService.updateById(orderLogistics);
            }
        });

        return true;
    }

    @Override
    public List<String> companys() {
        return logisticsMapper.companys();
    }

    @Override
    public boolean confirmLogistics(long logisticsId) {
        logisticsMapper.confirm(logisticsId);
        new Thread(() -> {
            LambdaQueryWrapper<OrderLogistics> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(OrderLogistics::getLogisticsId, logisticsId);
            List<OrderLogistics> orderLogistics = iOrderLogisticsService.list(queryWrapper);
            orderLogistics.forEach(logistics -> {
                Long itemId = logistics.getItemId();
                Long orderId = logistics.getOrderId();
                OrderItem orderItem = iOrderItemService.findByOrderIdAndItemId(itemId, orderId);
                int i = logisticsMapper.packingCount(itemId, orderId);
                if (i == 0 && orderItem.getSize().equals(orderItem.getShippedSize())) {
                    orderItem.setStatus(OrderItemStatusEnum.YWC);
                    iOrderItemService.updateById(orderItem);
                }
            });
        }).start();

        return true;
    }

    @Override
    public List<Logistics> listLogistics(long custId) {
        LambdaQueryWrapper<Logistics> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Logistics::getCustId, custId);
        return logisticsMapper.selectList(queryWrapper);
    }

    @Override
    public LogisticsResp detailLogistics(long logisticsId) {
        Logistics logistics = logisticsMapper.selectById(logisticsId);
        LogisticsResp logisticsResp = new LogisticsResp();
        BeanUtils.copyProperties(logistics, logisticsResp);

        logisticsResp.setOrderLogistics(iOrderLogisticsService.orderLogisticsDetail(logisticsId));
        return logisticsResp;
    }

    @Override
    public IPage<ListLogisticsForStorage> getSendGoodsList(PageParam pageParam, Map<String, Object> queryParam) {
        //分页信息
        Page<ListLogisticsForStorage> page = new Page<>();
        page.setSize(pageParam.getSize());
        page.setCurrent(pageParam.getCurrentPage());
        QueryWrapper<ListLogisticsForStorage> query = new QueryWrapper<>();
        query.allEq(queryParam);

        return logisticsMapper.getSendGoodsList(page, query);
    }
}
